/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#include "MkPsStreamSource.h"
#include "MkPsDemuxer.h"
#include "MkUtil/MkLog.h"

CMkPsStreamSource::CMkPsStreamSource()
    : CMkMediaSource(MkMediaSourceStreamPs)
    , m_pPsDemuxer(new CMkPsDemuxer)
    , m_nOffset(0)
    , m_MaxLen(LenHalfM)
    , m_LastTimeStamp(0)
{
    m_pBuf = (Uint8 *)malloc(m_MaxLen);
}

Uint32 CMkPsStreamSource::InputDataSlice(const Uint8* pBuf, Uint32 nLen, Uint32 TimeStamp, BOOL bEndSlice/* = FALSE*/)
{
    if (nLen + m_nOffset > m_MaxLen) {
        MkWarningLog("input data is out range of pbuf pool len\n");
        m_nOffset = 0;
        return SystemError;
    }
    if (m_LastTimeStamp != TimeStamp
        && m_nOffset > 0) {
        InputPsPacket(m_pBuf, m_nOffset);
        m_nOffset = 0;
    }
    m_LastTimeStamp = TimeStamp;
    memcpy(m_pBuf + m_nOffset, pBuf, nLen);
    m_nOffset += nLen;
    if (bEndSlice) {
        InputPsPacket(m_pBuf, m_nOffset);
        m_nOffset = 0;
    }
    return NoneError;
}

Uint32 CMkPsStreamSource::InputData(Uint8* pBuf, Uint32 nLen, Uint32& nUsed)
{
    Uint32 ErrorCode = m_pPsDemuxer->Input(pBuf, nLen, nUsed);
    MkCheckErrorLog(ErrorCode, "input ps data failed\n");
    return CallbackEsPacket();
}

Uint32 CMkPsStreamSource::InputPsPacket(Uint8* pBuf, Uint32 nLen)
{
    Uint32 ErrorCode = m_pPsDemuxer->InputPsPacket(pBuf, nLen);
    MkCheckErrorLog(ErrorCode, "input ps packet failed\n");

    return CallbackEsPacket();
}

//Uint32 CMkPsStreamSource::Stop()
//{
//    return NoneError;
//}

const CMkAudioParam& CMkPsStreamSource::GetAudioParam() const
{
    return m_pPsDemuxer->GetAudioParam();
}

const CMkVideoParam& CMkPsStreamSource::GetVideoParam() const
{
    return m_pPsDemuxer->GetVideoParam();
}

Uint32 CMkPsStreamSource::CallbackEsPacket()
{
    MkEsPacket EsPacket;
    while (NoneError == m_pPsDemuxer->GetEsPacket(EsPacket)) {
        SetVideoParam(m_pPsDemuxer->GetVideoParam());
        SetAudioParam(m_pPsDemuxer->GetAudioParam());
        OnReadEsPacket(EsPacket);
    }
    return NoneError;
}

CMkPsStreamSource::~CMkPsStreamSource()
{
    MkFree(m_pBuf);
    MkDelete(m_pPsDemuxer);
}